"""
虚拟数据生成器

用于生成模拟的加密货币价格数据，不依赖真实交易所API
"""

import numpy as np
import pandas as pd
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Tuple
from ..utils.helpers import TimeUtils


class MockDataGenerator:
    """虚拟数据生成器"""
    
    def __init__(self, seed: int = 42):
        """
        初始化虚拟数据生成器
        
        Args:
            seed: 随机种子，确保数据可重现
        """
        np.random.seed(seed)
        self.seed = seed
        
        # 预设的虚拟价格基准
        self.base_prices = {
            'BTC-USDT': 45000.0,
            'ETH-USDT': 3000.0,
            'BNB-USDT': 300.0,
            'ADA-USDT': 0.5,
            'SOL-USDT': 100.0,
            'DOT-USDT': 8.0,
            'MATIC-USDT': 1.2,
            'AVAX-USDT': 25.0,
            'LINK-USDT': 15.0,
            'UNI-USDT': 7.0
        }
        
        # 波动率配置
        self.volatility_config = {
            '1m': 0.0005,   # 1分钟数据波动较小
            '5m': 0.001,    # 5分钟数据
            '15m': 0.002,   # 15分钟数据
            '30m': 0.003,   # 30分钟数据
            '1h': 0.005,    # 1小时数据
            '2h': 0.007,    # 2小时数据
            '4h': 0.01,     # 4小时数据
            '1d': 0.02,     # 日线数据波动较大
            '1w': 0.05      # 周线数据波动最大
        }
    
    def generate_kline_data(self, symbol: str, interval: str, 
                           start_time: datetime, end_time: datetime) -> pd.DataFrame:
        """
        生成K线数据
        
        Args:
            symbol: 交易对符号
            interval: 时间间隔
            start_time: 开始时间
            end_time: 结束时间
            
        Returns:
            包含OHLCV数据的DataFrame
        """
        # 获取基础价格
        base_price = self.base_prices.get(symbol, 1000.0)
        
        # 生成时间序列
        freq_map = {
            '1m': '1min',
            '5m': '5min', 
            '15m': '15min',
            '30m': '30min',
            '1h': '1H',
            '2h': '2H',
            '4h': '4H',
            '1d': '1D',
            '1w': '1W'
        }
        
        freq = freq_map.get(interval, '5min')
        timestamps = pd.date_range(start_time, end_time, freq=freq)
        
        if len(timestamps) == 0:
            return pd.DataFrame()
        
        # 获取波动率
        volatility = self.volatility_config.get(interval, 0.001)
        
        # 生成价格走势
        prices = self._generate_price_series(base_price, len(timestamps), volatility, interval)
        
        # 生成OHLCV数据
        data = []
        for i, timestamp in enumerate(timestamps):
            if i < len(prices):
                ohlcv = self._generate_ohlcv(prices[i], volatility, interval)
                ohlcv['timestamp'] = int(timestamp.timestamp())
                ohlcv['datetime'] = timestamp.strftime('%Y-%m-%d %H:%M:%S')
                data.append(ohlcv)
        
        df = pd.DataFrame(data)
        return df
    
    def _generate_price_series(self, base_price: float, length: int, 
                              volatility: float, interval: str) -> List[float]:
        """生成价格序列"""
        prices = [base_price]
        
        # 生成随机收益率
        returns = np.random.normal(0, volatility, length - 1)
        
        for i in range(length - 1):
            # 添加趋势和周期性
            trend_factor = 1000 if interval in ['1d', '1w'] else 100
            volatility_factor = 100 if interval in ['1d', '1w'] else 10
            
            # 长期趋势
            trend = 0.0001 * np.sin(i / trend_factor)
            # 短期波动
            cycle = volatility * 0.5 * np.sin(i / volatility_factor)
            
            price_change = returns[i] + trend + cycle
            new_price = prices[-1] * (1 + price_change)
            prices.append(max(new_price, 0.01))  # 确保价格为正
        
        return prices
    
    def _generate_ohlcv(self, base_price: float, volatility: float, 
                       interval: str) -> Dict:
        """生成单个K线的OHLCV数据"""
        # 价格范围
        price_range = base_price * volatility * 2
        
        # 生成开盘和收盘价
        open_price = base_price + np.random.uniform(-price_range/2, price_range/2)
        close_price = base_price + np.random.uniform(-price_range/2, price_range/2)
        
        # 生成最高和最低价
        high_price = max(open_price, close_price) + np.random.uniform(0, price_range/2)
        low_price = min(open_price, close_price) - np.random.uniform(0, price_range/2)
        
        # 确保价格合理性
        high_price = max(high_price, open_price, close_price)
        low_price = min(low_price, open_price, close_price)
        low_price = max(low_price, 0.01)  # 确保最低价为正
        
        # 生成成交量
        volume_base = self._get_volume_base(interval)
        volume = np.random.uniform(volume_base * 0.5, volume_base * 2)
        
        return {
            'open': round(open_price, 2),
            'high': round(high_price, 2),
            'low': round(low_price, 2),
            'close': round(close_price, 2),
            'volume': round(volume, 2)
        }
    
    def _get_volume_base(self, interval: str) -> float:
        """获取基础成交量"""
        volume_map = {
            '1m': 1000,
            '5m': 800,
            '15m': 600,
            '30m': 500,
            '1h': 400,
            '2h': 350,
            '4h': 300,
            '1d': 200,
            '1w': 100
        }
        return volume_map.get(interval, 500)
    
    def generate_ticker_data(self, symbol: str) -> Dict:
        """
        生成实时行情数据
        
        Args:
            symbol: 交易对符号
            
        Returns:
            包含实时价格信息的字典
        """
        base_price = self.base_prices.get(symbol, 1000.0)
        
        # 添加小幅随机波动
        price_change = np.random.uniform(-0.02, 0.02)  # ±2%的波动
        current_price = base_price * (1 + price_change)
        
        # 生成24小时变化
        change_24h = np.random.uniform(-0.1, 0.1)  # ±10%的24小时变化
        
        return {
            'symbol': symbol,
            'price': round(current_price, 2),
            'last': round(current_price, 2),
            'bid': round(current_price * 0.999, 2),
            'ask': round(current_price * 1.001, 2),
            'change_24h': round(change_24h * 100, 2),
            'volume_24h': round(np.random.uniform(10000, 100000), 2),
            'high_24h': round(current_price * 1.05, 2),
            'low_24h': round(current_price * 0.95, 2),
            'timestamp': int(datetime.now().timestamp() * 1000)
        }
    
    def get_supported_symbols(self) -> List[str]:
        """获取支持的交易对列表"""
        return list(self.base_prices.keys())
    
    def update_base_price(self, symbol: str, price: float) -> None:
        """更新基础价格"""
        self.base_prices[symbol] = price
    
    def add_symbol(self, symbol: str, base_price: float) -> None:
        """添加新的交易对"""
        self.base_prices[symbol] = base_price


# 全局实例
mock_data_generator = MockDataGenerator()